package com.slunk.platforms;

import com.badlogic.gdx.graphics.g2d.BitmapFont;
import com.badlogic.gdx.graphics.g2d.SpriteBatch;
import com.badlogic.gdx.graphics.g2d.BitmapFont.TextBounds;
import com.badlogic.gdx.utils.Timer;
import com.badlogic.gdx.utils.Timer.Task;
import com.slunk.platforms.SLabelEvents;

public class SLabel {
	//public String choice;
	public String displayLabel;
	public String originalLabel;
	public BitmapFont drawer;
	public Object userData;
	public float x;
	public float y;
	public float width;
	public float height;
	public SLabelEvents eventHandler;
	
	//crawl stuff
	Timer crawlTimer;
	int crawlIndex;
	
	//
	public boolean isDisplaying = false;
	public boolean isCrawling = false;
	
	/**
	 * 
	 * @param choice
	 * @param x
	 * @param y
	 * @param width
	 */
	public SLabel(String choice, float x, float y, float width) {
		this.originalLabel = choice;
		this.displayLabel = ""; 
		this.drawer = new BitmapFont();
		this.x = x;
		this.y = y;
		this.width = width;
		this.height = this.getBounds().height;
	}
	
	/**
	 * 
	 * @param choice
	 * @param x
	 * @param y
	 */
	public SLabel(String choice, float x, float y) {
		this(choice,x,y,100);
	}
	
	/**
	 * 
	 * @param choice
	 */
	public SLabel(String choice) {
		this(choice,0,0,100);
	}

	/**
	 * Stops the crawl timer
	 */
	public void stopAll() {
		crawlTimer.stop();
	}
	
	/**
	 * Setting the event handler to receive events about this particular object
	 * @param eventHandler
	 */
	public void setEventHandler(SLabelEvents eventHandler) {
		this.eventHandler = eventHandler;
	}
	
	/**
	 * Helper method to begin displaying the text by crawling it
	 * 
	 * @param index At what index to start the crawl at. 0 starts at the beginning of the string
	 * @param delay The delay in when the crawl should begin
	 * @param speed The speed at which the crawl travels
	 */
	public void crawlLabel(int index, float delay, float speed) {
		isCrawling = true;
		crawlIndex = index;
		//maybe redundant but might as well set the display string to the empty string
		displayLabel = "";
		crawlTimer = new Timer();
		crawlTimer.scheduleTask( new Task() {
			@Override
			public void run() {
				displayLabel = displayLabel + originalLabel.charAt(crawlIndex);
            	if (crawlIndex < originalLabel.length() - 1) {
            		crawlIndex = crawlIndex + 1;
            	} else {
            		if (eventHandler != null) {
            			eventHandler.didFinishCrawling(SLabel.this);
            		}
            		crawlTimer.stop();
            		isCrawling = false;
            	}
			}
		}, delay,speed);	
	}
	public void dismissCrawlingLabel() {
		isCrawling = false;
		if (crawlTimer != null) {
			crawlTimer.stop();
		}
	}
	
	/**
	 * Helper method to begin displaying the text 
	 */
	public void displayLabel() {
		isDisplaying = true;
		setDisplayLabel(getOriginalLabel());
	}
	public void dismissDisplayLabel() {
		isDisplaying = false;
		displayLabel = "";
	}
	
	public boolean isCrawlingLabel() {
		return isCrawling;
	}
	public boolean isDisplayingLabel() {
		return isDisplaying;
	}
	
	public void setUserData (Object userData) {
		this.userData = userData;
	}
	
	public Object getUserData() {
		return userData;
	}
	
	public void setPosition(float x, float y) {
		this.x = x;
		this.y = y;
	}
	
	public void setDisplayLabel(String label) {
		if (!label.equals(originalLabel)) {
			setOriginalLabel(label);
		}
		displayLabel = label;
	}
	
	public String getDisplayLabel() {
		return displayLabel;
	}
	
	public void setOriginalLabel(String label) {
		originalLabel = label;
	}
	
	public String getOriginalLabel() {
		return originalLabel;
	}
	
	public void drawSelf(SpriteBatch batch) {
		drawer.drawWrapped(batch, getDisplayLabel(), x, y, width);
	}
	
	public TextBounds getBounds() {
		return drawer.getWrappedBounds(getOriginalLabel(), width);
	}
	
	public boolean containsMousePosition(float x, float y) {
		TextBounds bounds = getBounds();
		if (
				(x > this.x) && (x < this.x + bounds.width) 
				&&
				(y < this.y) && (y > this.y - bounds.height)
				)
		{
			return true;
		}
		return false;
	}
}
